<?php

namespace app\cms\service\dataoke;

use app\cms\service\dataoke\stub\GetJdGoodsSearchDto;
use app\cms\service\dataoke\stub\GetJdGoodsSearchResultItem;
use app\cms\service\entities\Good;
use app\cms\service\SalesPlatformInterface;
use GetJdGoodsSearch;
use GetSinglePromotionUnionConvert;
use think\Url;

require_once __DIR__. DS. 'openapi-sdk-php-master'. DS. 'api'. DS. 'DtkClient.php';

class DataokePlatform implements SalesPlatformInterface
{
    const APP_KEY = '62bf091138fa6';
    const APP_SECRET = '4059d8f68219bfe3e716c9ec4f52b69b';
    const VENDOR_CLASS_PATH = __DIR__. DS. 'openapi-sdk-php-master'. DS. 'api'. DS;
    const JD_UNION_ID = '1001459188'; // 京东联盟id

    public function __construct(){
        require_once static::VENDOR_CLASS_PATH. 'DtkClient.php';
    }

    /**
     * @return \DtkClient
     */
    private function getClient($className, $apiVersion)
    {
        if (!class_exists($className, false)) {
            $file = static::VENDOR_CLASS_PATH. str_replace('\\', '', $className). '.php';
            if (is_file($file)) {
                require_once $file;
            }
            if (!class_exists($className, false)) {
                throw new \RuntimeException("Class definition not found '$className' in file $file.");
            }
        }

        $client = new $className();

        $client->setAppKey(static::APP_KEY);
        $client->setAppSecret(static::APP_SECRET);
        $client->setVersion($apiVersion);

        return $client;
    }

    /**
     * @param string $keyword
     * @param int $page
     * @param int $pageSize
     * @return array|Good[]
     */
    public function queryGoods(string $keyword, int $page, int $pageSize): array
    {
        // 京东联盟商品搜索
        // https://www.dataoke.com/pmc/api-d.html?id=70
        /** @var GetJdGoodsSearch $client */
        $client = $this->getClient(GetJdGoodsSearch::class, 'v1.0.0');

        $client->keyword = $keyword;
        $client->isCoupon = 1;
        $client->pageId = $page > 0 ? $page : 1;
        $client->pageSize = ($pageSize > 0 && $pageSize <= 30) ? $pageSize : 20;

        $resObj = $this->execute($client, __METHOD__);

        /** @var GetJdGoodsSearchDto $data */
        $data = $resObj->data;
        $list = (array)($data->list);
        $pageId = $data->pageId;
        $totalNum = $data->totalNum;

        return array_map(function($item) {
            /** @var GetJdGoodsSearchResultItem $item */
            $good = new Good();
            $good->platform = 'jd';
            $good->promPrice = $item->lowestCouponPrice;
            $good->rawPrice = $item->price;
            $good->title = $item->skuName;
            $good->picUrl = $item->imageUrlList[0];
            $good->iid = "{$item->skuId}_{$item->spuid}";
            $good->cates = "{$item->cid1}_{$item->cid2}_{$item->cid3}";
            $good->clickUrl = Url::build("cms/api/click", ['c' => $this->genClickInfoStr($item)], false);
            return $good;
        }, $data->list);

    }

    /**
     * TODO加密算法：
     * 1. 使用掩码补全到127位长度，并附加一个三位数字记录实际长度
     * 2. 按13为分组数进行一次栅栏加密
     * 3. 以8位基数进行一次加强凯撒移位（每一位字符的偏移量等于它在当前字符串中的位置）
     * 4. 按5为分组数进行一次栅栏加密
     * 5. 以3为基数进行一次加强凯撒移位
     * 6. 按2为分组数进行一次栅栏加密
     * 3. base64编码
     *
     * @param GetJdGoodsSearchResultItem $item
     * @return string
     */
    private function genClickInfoStr($item) {
        return base64_encode($item->materialUrl);
    }

    /**
     * TODO 参考 genClickInfoStr 做解密
     *
     * @param $clickInfoStr
     * @return false|string
     */
    private function parseClickInfoStr($clickInfoStr) {
        return base64_decode($clickInfoStr, true);
    }

    private function execute(\DtkClient $client, $localMethod) {

        try {
            $resText = $client->request();
        } catch (\Exception $e) {
            throw new \RuntimeException($localMethod. '(): 接口请求失败。Error: '. $e->getMessage());
        }

        $resObj = json_decode($resText);
        if (json_last_error() != 0) {
            throw new \RuntimeException($localMethod. '(): 接口响应无法解析为json. Error: '. json_last_error_msg(). '. ResponseText: '. $resText);
        }

        if ($resObj->code !== 0) {
            throw new \RuntimeException($localMethod. '(): 接口处理失败: ['. $resObj->code. ']'. $resObj->msg
                . '. RequestId: '. $resObj->requestId
                . '. RequestTime: '. $resObj->time
                . '. RequestParams: '. $client->getRequestParamsStr());
        }

        return $resObj;
    }


    /**
     * @param string $clickInfoStr
     * @return string
     */
    public function convertClickUrl($clickInfoStr){

        $materialUrl = $this->parseClickInfoStr($clickInfoStr);
        if (empty($materialUrl)) {
            throw new \RuntimeException("Invalid click info param.");
        }

        // 京东联盟商品转链
        // https://www.dataoke.com/kfpt/api-d.html?id=52
        /** @var GetSinglePromotionUnionConvert $client */
        $client = $this->getClient(GetSinglePromotionUnionConvert::class, 'v1.0.0');

        $client->unionId = self::JD_UNION_ID;
        $client->materialId = $materialUrl;

        $resObj = $this->execute($client, __METHOD__);

        return $resObj->data->shortUrl;
    }
}